#include <MQTTClient.h>  //MQTT客户端函数库
#include <unistd.h>
#include <stdio.h>
#include <string.h>

//定义接收消息处理函数（回调）
//参数1：通过MQTTClient_setCallbacks传递的参数
//参数2：接收消息的主题名称
//参数3：接收消息的主题名称长度，当主题名称中有1个以上的0字符，需要使用此字段
//参数4：接收到的消息
//返回值：消息成功处理返回true（1），消息处理失败返回false（0）
int messageArrived(void *context, char *topicName, int topicLen, MQTTClient_message *message)
{
	char *payload = message->payload;

	printf("> ");
	// payloadlen 消息内容长度
	//消息内容放在 message->payload 字段指向的内存中
	for (int i = 0; i < message->payloadlen; i++)
	{
		putchar(payload[i]);
	}
	putchar('\n');

	return 1;
}

int main()
{
	MQTTClient client;
	//定义连接选项变量并初始化
	MQTTClient_connectOptions options = MQTTClient_connectOptions_initializer;
	int error;

	//创建MQTT客户端
	//参数1：客户端变量的内存地址
	//参数2：MQTT服务器地址(协议://服务器地址或域名:端口号)
	//参数3：客户端ID
	//参数4：消息缓存方式（文件/内存）
	//参数5：用户自定义缓存方式的时候使用（默认填NULL）
        error = MQTTClient_create(&client, "tcp://bemfa.com:9501",
                                  "4e78c607dbbc9f4d6b5c16ffa5622fb7",
                                  MQTTCLIENT_PERSISTENCE_NONE, NULL);
        if (error != MQTTCLIENT_SUCCESS)
	{
		printf("Create client error\n");
		return 1;
	}

	//注册消息处理函数
	//此函数必须在连接服务器之前调用
	//参数1：客户端变量
	//参数2：传递给回调函数的参数，不需要传递参数时填NULL
	//参数3：当客户端与服务器断开连接的时候调用的回调函数，不需要处理的时候填NULL
	//参数4：当客户端收到消息后调用此函数进行处理，不需要处理的时候填NULL
	//参数5：消息发布成功后会调用此函数，不需要处理的时候填NULL
	error = MQTTClient_setCallbacks(client, NULL, NULL, messageArrived, NULL);
	if (error != MQTTCLIENT_SUCCESS) {
		printf("Set callbacks error\n");
	}

	//连接MQTT服务器
	error = MQTTClient_connect(client, &options);
	if (error != MQTTCLIENT_SUCCESS) {
		printf("Server connect error\n");
		return 1;
	}

	//订阅主题
	//参数1：客户端变量
	//参数2：需要订阅的主题名称
	//参数3：服务质量级别（0-2）(恰好一次)
	error = MQTTClient_subscribe(client, "test", 0);
	if (error != MQTTCLIENT_SUCCESS) {
		printf("Subscribe error\n");
	}

	while(1)
	{
		MQTTClient_message msg = MQTTClient_message_initializer;
		MQTTClient_deliveryToken dt;

		msg.payload = "hello";
		msg.payloadlen = strlen(msg.payload);
		msg.qos = 0;

		printf("< %s\n", (char *)msg.payload);
		error = MQTTClient_publishMessage(client, "test/up", &msg, &dt);
		if (error != MQTTCLIENT_SUCCESS) {
			printf("message publish error: %d\n", error);
		}

		//等待消息发送完成
		MQTTClient_waitForCompletion(client, dt, 1000);

		sleep(10);
	}

	// 断开服务器连接
	//参数2：超时时间（单位毫秒）
	MQTTClient_disconnect(client, 1000);

	// 释放客户端资源
	MQTTClient_destroy(&client);

	return 0;
}

